﻿using System;
using System.Collections.Generic;
using System.Linq;
using ReagentStore.DAL;
using ReagentStore.ERM;
using ReagentStore.Resources.Properties;
using ReagentStore.UTL;

namespace ReagentStore.BLL
{
	public class ProductBLL
	{
		public readonly ProductDAL DALAccessor = new ProductDAL();

		private void CheckParams(Product product)
		{
			product.Manufacturer = product.Manufacturer.Regular();
			product.Specification = product.Specification.Regular();
			product.Batch = product.Batch.Regular();
			product.ExpirationDate = product.ExpirationDate.ToUniversalTime();

			if (string.IsNullOrEmpty(product.Manufacturer)
			    || string.IsNullOrEmpty(product.Specification)
			    || string.IsNullOrEmpty(product.Batch))
				throw new ApplicationException(DefaultResources.PRODUCT_INVALID_PARAM);

			if (product.ExpirationDate.Date <= DateTime.Today.ToUniversalTime())
				throw new ApplicationException(DefaultResources.PRODUCT_INVALID_PARAM);

			Product exist = DALAccessor.GetEntities().SingleOrDefault(s =>
			                                                          product.Manufacturer.Equals(s.Manufacturer,
			                                                                                      StringComparison.
			                                                                                      	CurrentCultureIgnoreCase)
			                                                          &&
			                                                          product.Specification.Equals(s.Specification,
			                                                                                       StringComparison.
			                                                                                       	CurrentCultureIgnoreCase)
			                                                          &&
			                                                          product.Batch.Equals(s.Batch,
			                                                                               StringComparison.
			                                                                               	CurrentCultureIgnoreCase)
			                                                          && product.ExpirationDate.Equals(s.ExpirationDate));
			if (exist != null)
				if (product.ReagentID.Equals(exist.ReagentID))
					throw new ApplicationException(DefaultResources.PRODUCT_EXIST);

			Reagent reagent = new ReagentDAL().GetEntityById(product.ReagentID);
			if (reagent == null)
				throw new ApplicationException(DefaultResources.REAGENT_NOT_FOUND);
		}

		private void CheckEntityUpdatable(Product product)
		{
			Product updation = DALAccessor.GetEntityById(product.ProductID);
			if (updation == null)
				throw new ApplicationException(DefaultResources.PRODUCT_NOT_FOUND);
		}

		public void Insert(Product product)
		{
			CheckParams(product);
			DALAccessor.Insert(product);
		}

		public void Update(Product product)
		{
			CheckParams(product);
			CheckEntityUpdatable(product);
			DALAccessor.Update(product);
		}

		public void Delete(Product product)
		{
			CheckEntityUpdatable(product);

			int quantity = DALAccessor.GetEntitiesByReagentId(product.ReagentID).Sum(p => p.Quantity());
			if (quantity - product.Quantity() > 0)
				DALAccessor.Delete(product);
			else
				throw new ApplicationException(DefaultResources.PRODUCT_INVALID_PARAM);
		}

		public IList<Product> GetExpirationList()
		{
			var reagentDal = new ReagentDAL();
			DateTime today = DateTime.Today.ToUniversalTime();

			return DALAccessor.GetEntities()
				.Where(product => (product.ExpirationDate - today).Days <= reagentDal.GetEntityById(product.ReagentID).AlertPeriod)
				.ToList();
		}

		public int GetQuantity(Product product)
		{
			var recordDAL = new RecordDAL();

			return recordDAL.GetEntitiesByProductId(product.ProductID).Sum(record => record.Quantity());
		}
	}
}